import { defineStore } from 'pinia'
import { ref } from 'vue'
import { v4 as uuidv4 } from 'uuid'

// 机柜类型枚举
export enum CabinetType {
    SERVER = 'server',
    AC = 'ac',
    NETWORK = 'network',
    POWER = 'power'
}

// 设备类型枚举
export enum DeviceType {
    SERVER = 'server',
    SWITCH = 'switch',
    ROUTER = 'router',
    STORAGE = 'storage',
    FIREWALL = 'firewall'
}

// 机柜类型配置
export const CabinetTypeConfig = {
    [CabinetType.SERVER]: { name: '服务器机柜', color: '#666666', icon: '🖥️' },
    [CabinetType.AC]: { name: '空调机柜', color: '#4a90e2', icon: '❄️' },
    [CabinetType.NETWORK]: { name: '网络机柜', color: '#50c878', icon: '🌐' },
    [CabinetType.POWER]: { name: '配电机柜', color: '#ff6b6b', icon: '⚡' }
}

// 设备类型配置
export const DeviceTypeConfig = {
    [DeviceType.SERVER]: { name: '服务器', color: '#2196F3', icon: '🖥️' },
    [DeviceType.SWITCH]: { name: '交换机', color: '#4CAF50', icon: '🔌' },
    [DeviceType.ROUTER]: { name: '路由器', color: '#FF9800', icon: '📡' },
    [DeviceType.STORAGE]: { name: '存储设备', color: '#9C27B0', icon: '💾' },
    [DeviceType.FIREWALL]: { name: '防火墙', color: '#F44336', icon: '🛡️' }
}

/**
 * 基础设备类 - 使用 getter/setter 进行优雅的属性管理
 */
export class Device {
    public readonly id: string = uuidv4()
    protected _name: string
    protected _description: string
    protected _rackPosition: number = 1 // U位置
    protected _rackUnits: number = 1 // 占用U数
    protected _powerConsumption: number = 0 // 功耗(W)
    protected _type: DeviceType

    constructor(name: string, description: string = '', type: DeviceType = DeviceType.SERVER) {
        this._name = name
        this._description = description
        this._type = type
    }

    // 优雅的 getter/setter 实现
    get name(): string {
        return this._name
    }

    set name(value: string) {
        if (!value?.trim()) {
            throw new Error('设备名称不能为空')
        }
        this._name = value.trim()
    }

    get description(): string {
        return this._description
    }

    set description(value: string) {
        this._description = value?.trim() || ''
    }

    get rackPosition(): number {
        return this._rackPosition
    }

    set rackPosition(value: number) {
        if (value < 1 || value > 47) {
            throw new Error('机架位置必须在1-47U之间')
        }
        this._rackPosition = value
    }

    get rackUnits(): number {
        return this._rackUnits
    }

    set rackUnits(value: number) {
        if (value < 1 || value > 10) {
            throw new Error('机架单位必须在1-10U之间')
        }
        this._rackUnits = value
    }

    get powerConsumption(): number {
        return this._powerConsumption
    }

    set powerConsumption(value: number) {
        if (value < 0) {
            throw new Error('功耗不能为负数')
        }
        this._powerConsumption = value
    }

    get type(): DeviceType {
        return this._type
    }

    // 业务方法
    getOccupiedRackPositions(): number[] {
        return Array.from({ length: this._rackUnits }, (_, i) => this._rackPosition + i)
    }

    // 计算属性示例 - 自动计算设备状态描述
    get statusDescription(): string {
        const positions = this.getOccupiedRackPositions()
        const config = DeviceTypeConfig[this._type]
        return `${config.name} - 位置: ${positions.join(',')}U - 功耗: ${this._powerConsumption}W`
    }
}

/**
 * 服务器设备 - 继承基础设备类
 */
export class ServerDevice extends Device {
    protected _cpu: string = ''
    protected _memory: string = ''
    protected _storage: string = ''
    protected _operatingSystem: string = ''

    constructor(name: string, description: string = '') {
        super(name, description, DeviceType.SERVER)
        this._rackUnits = 1 // 服务器通常占用1U
    }

    get cpu(): string { return this._cpu }
    set cpu(value: string) { this._cpu = value?.trim() || '' }

    get memory(): string { return this._memory }
    set memory(value: string) { this._memory = value?.trim() || '' }

    get storage(): string { return this._storage }
    set storage(value: string) { this._storage = value?.trim() || '' }

    get operatingSystem(): string { return this._operatingSystem }
    set operatingSystem(value: string) { this._operatingSystem = value?.trim() || '' }

    // 服务器特有的计算属性
    get specs(): string {
        const parts = [this._cpu, this._memory, this._storage].filter(Boolean)
        return parts.length > 0 ? parts.join(' | ') : '未配置规格'
    }
}

/**
 * 网络设备 - 继承基础设备类
 */
export class NetworkDevice extends Device {
    protected _portCount: number = 0
    protected _managementIP: string = ''
    protected _firmware: string = ''

    constructor(name: string, description: string = '', type: DeviceType = DeviceType.SWITCH) {
        super(name, description, type)
        this._rackUnits = 1 // 网络设备通常占用1U
    }

    get portCount(): number { return this._portCount }
    set portCount(value: number) {
        if (value < 0) throw new Error('端口数量不能为负数')
        this._portCount = value
    }

    get managementIP(): string { return this._managementIP }
    set managementIP(value: string) {
        // 简单的IP验证
        if (value && !/^(\d{1,3}\.){3}\d{1,3}$/.test(value)) {
            throw new Error('无效的IP地址格式')
        }
        this._managementIP = value?.trim() || ''
    }

    get firmware(): string { return this._firmware }
    set firmware(value: string) { this._firmware = value?.trim() || '' }

    // 网络设备特有的计算属性
    get networkInfo(): string {
        const info = []
        if (this._portCount > 0) info.push(`${this._portCount}端口`)
        if (this._managementIP) info.push(`管理IP: ${this._managementIP}`)
        if (this._firmware) info.push(`固件: ${this._firmware}`)
        return info.length > 0 ? info.join(' | ') : '未配置网络信息'
    }
}

/**
 * 存储设备 - 继承基础设备类
 */
export class StorageDevice extends Device {
    protected _capacity: string = ''
    protected _raidLevel: string = ''
    protected _interfaceType: string = ''

    constructor(name: string, description: string = '') {
        super(name, description, DeviceType.STORAGE)
        this._rackUnits = 2 // 存储设备通常占用2U
    }

    get capacity(): string { return this._capacity }
    set capacity(value: string) { this._capacity = value?.trim() || '' }

    get raidLevel(): string { return this._raidLevel }
    set raidLevel(value: string) { this._raidLevel = value?.trim() || '' }

    get interfaceType(): string { return this._interfaceType }
    set interfaceType(value: string) { this._interfaceType = value?.trim() || '' }

    // 存储设备特有的计算属性
    get storageInfo(): string {
        const info = []
        if (this._capacity) info.push(`容量: ${this._capacity}`)
        if (this._raidLevel) info.push(`RAID: ${this._raidLevel}`)
        if (this._interfaceType) info.push(`接口: ${this._interfaceType}`)
        return info.length > 0 ? info.join(' | ') : '未配置存储信息'
    }
}

/**
 * 机柜类 - 也使用 getter/setter 进行属性管理
 */
export class Cabinet {
    public readonly id: string = uuidv4()
    protected _name: string
    protected _description: string
    protected _position: number
    protected _width: number
    protected _height: number
    protected _depth: number
    protected _color: string
    protected _devices: Device[] = []
    protected _type: CabinetType
    protected _rowId: string

    constructor(
        name: string,
        description: string,
        position: number,
        width: number = 600,
        height: number = 2000,
        depth: number = 1400,
        color: string = '#666666',
        rowId: string,
        type: CabinetType = CabinetType.SERVER
    ) {
        this._name = name
        this._description = description
        this._position = position
        this._width = width
        this._height = height
        this._depth = depth
        this._color = color
        this._rowId = rowId
        this._type = type
    }

    // 优雅的 getter/setter
    get name(): string { return this._name }
    set name(value: string) {
        if (!value?.trim()) throw new Error('机柜名称不能为空')
        this._name = value.trim()
    }

    get description(): string { return this._description }
    set description(value: string) { this._description = value?.trim() || '' }

    get position(): number { return this._position }
    get width(): number { return this._width }
    set width(value: number) {
        if (value < 500 || value > 1000) throw new Error('机柜宽度必须在500-1000mm之间')
        this._width = value
    }

    get height(): number { return this._height }
    get depth(): number { return this._depth }
    get color(): string { return this._color }
    set color(value: string) { this._color = value }

    get type(): CabinetType { return this._type }
    set type(value: CabinetType) { this._type = value }

    get devices(): Device[] { return [...this._devices] } // 返回副本

    get rowId(): string { return this._rowId }

    // 业务方法
    addDevice(device: Device): void {
        // 检查U位置冲突
        const occupiedPositions = device.getOccupiedRackPositions()
        const conflicts = this._devices.some(existingDevice => {
            const existingPositions = existingDevice.getOccupiedRackPositions()
            return occupiedPositions.some(pos => existingPositions.includes(pos))
        })

        if (conflicts) {
            throw new Error('设备位置冲突')
        }

        this._devices.push(device)
    }

    removeDevice(deviceId: string): boolean {
        const index = this._devices.findIndex(d => d.id === deviceId)
        if (index > -1) {
            this._devices.splice(index, 1)
            return true
        }
        return false
    }

    // 计算属性
    get deviceCount(): number {
        return this._devices.length
    }

    get totalPowerConsumption(): number {
        return this._devices.reduce((sum, device) => sum + device.powerConsumption, 0)
    }

    get occupiedUnits(): number {
        return this._devices.reduce((sum, device) => sum + device.rackUnits, 0)
    }

    get availableUnits(): number {
        return 47 - this.occupiedUnits // 标准机柜47U
    }

    get statusSummary(): string {
        const total = this.totalPowerConsumption
        const occupied = this.occupiedUnits
        return `设备: ${this.deviceCount} | 占用: ${occupied}U/47U | 功耗: ${total}W`
    }
}

/**
 * 行/列类 - 包含多个机柜的抽象
 */
export class Row {
    public readonly id: string = uuidv4()
    protected _name: string
    protected _description: string
    protected _position: { x: number; y: number; z: number }
    protected _cabinets: Cabinet[] = []
    protected _spacing: number
    protected _color: string
    protected _height: number
    protected _depth: number

    constructor(
        name: string = 'Row',
        description: string = 'Row',
        position: { x: number; y: number; z: number } = { x: 0, y: 0, z: 0 },
        cabinets: Cabinet[] = [],
        spacing: number = 0,
        color: string = '#2c3e50',
        height: number = 2400,
        depth: number = 1400
    ) {
        this._name = name
        this._description = description
        this._position = position
        this._cabinets = cabinets
        this._spacing = spacing
        this._color = color
        this._height = height
        this._depth = depth
    }

    // Getters and Setters
    get name(): string { return this._name }
    set name(value: string) {
        if (!value?.trim()) throw new Error('行名称不能为空')
        this._name = value.trim()
    }

    get description(): string { return this._description }
    set description(value: string) { this._description = value?.trim() || '' }

    get position(): { x: number; y: number; z: number } { return { ...this._position } }
    set position(value: { x: number; y: number; z: number }) { this._position = { ...value } }

    get cabinets(): Cabinet[] { return this._cabinets } // 返回实际实例而不是副本
    get spacing(): number { return this._spacing }
    set spacing(value: number) {
        if (value < 0) throw new Error('机柜间距不能为负数')
        this._spacing = value
    }

    get color(): string { return this._color }
    set color(value: string) { this._color = value }

    get height(): number { return this._height }
    set height(value: number) {
        if (value < 1800 || value > 3000) throw new Error('行高度必须在1800-3000mm之间')
        this._height = value
        // 更新所有机柜的高度
        this._cabinets.forEach(cabinet => cabinet['_height'] = value)
    }

    get depth(): number { return this._depth }
    set depth(value: number) {
        if (value < 800 || value > 2000) throw new Error('行深度必须在800-2000mm之间')
        this._depth = value
        // 更新所有机柜的深度
        this._cabinets.forEach(cabinet => cabinet['_depth'] = value)
    }

    // 业务方法
    addCabinet(cabinet: {
        name: string;
        description: string;
        width?: number;
        color?: string;
        type?: CabinetType;
    }): Cabinet {
        const cabinetType = cabinet.type || CabinetType.SERVER
        const defaultColor = CabinetTypeConfig[cabinetType].color

        const newCabinet = new Cabinet(
            cabinet.name,
            cabinet.description,
            this._cabinets.length,
            cabinet.width || 600,
            this._height,
            this._depth,
            cabinet.color || defaultColor,
            this.id,
            cabinetType
        )
        this._cabinets.push(newCabinet)
        return newCabinet
    }

    removeCabinet(cabinetIdOrObject: string | Cabinet): void {
        const cabinetId = typeof cabinetIdOrObject === 'string' ? cabinetIdOrObject : cabinetIdOrObject.id
        const index = this._cabinets.findIndex(c => c.id === cabinetId)
        if (index > -1) {
            this._cabinets.splice(index, 1)
            this.recalculateCabinetPositions()
        }
    }

    private recalculateCabinetPositions(): void {
        this._cabinets.forEach((cabinet, index) => {
            cabinet['_position'] = index
        })
    }

    // 计算属性
    get cabinetCount(): number {
        return this._cabinets.length
    }

    get totalLength(): number {
        if (this._cabinets.length === 0) return 0
        const totalCabinetWidth = this._cabinets.reduce((sum, cabinet) => sum + cabinet.width, 0)
        const totalSpacing = (this._cabinets.length - 1) * this._spacing
        return totalCabinetWidth + totalSpacing
    }

    get totalDeviceCount(): number {
        return this._cabinets.reduce((sum, cabinet) => sum + cabinet.deviceCount, 0)
    }

    get totalPowerConsumption(): number {
        return this._cabinets.reduce((sum, cabinet) => sum + cabinet.totalPowerConsumption, 0)
    }

    // 计算机柜在3D空间中的绝对位置
    calculateCabinetPosition(index: number): { x: number; y: number; z: number } {
        let xOffset = 0
        for (let i = 0; i < index; i++) {
            xOffset += this._cabinets[i].width + this._spacing
        }

        return {
            x: this._position.x + xOffset,
            y: this._position.y,
            z: this._position.z
        }
    }
}

// 工厂函数，用于创建不同类型的设备
export class DeviceFactory {
    static createServer(name: string, description?: string): ServerDevice {
        return new ServerDevice(name, description)
    }

    static createSwitch(name: string, description?: string): NetworkDevice {
        return new NetworkDevice(name, description, DeviceType.SWITCH)
    }

    static createRouter(name: string, description?: string): NetworkDevice {
        return new NetworkDevice(name, description, DeviceType.ROUTER)
    }

    static createStorage(name: string, description?: string): StorageDevice {
        return new StorageDevice(name, description)
    }

    static createFirewall(name: string, description?: string): NetworkDevice {
        return new NetworkDevice(name, description, DeviceType.FIREWALL)
    }
}

// Pinia Store
export const useDataCenterStore = defineStore('dataCenter', () => {
    const config = ref({
        name: 'Data Center',
        description: 'Data Center',
    })

    const rows = ref<Row[]>([])

    function addRow(rowData: {
        name: string;
        description: string;
        position: { x: number; y: number; z: number };
        spacing?: number;
        height?: number;
        depth?: number;
        color?: string;
    }): Row {
        const row = new Row(
            rowData.name,
            rowData.description,
            rowData.position,
            [],
            rowData.spacing || 0,
            rowData.color || '#2c3e50',
            rowData.height || 2400,
            rowData.depth || 1400
        )
        rows.value.push(row)
        return row
    }

    function removeRow(id: string): void {
        const index = rows.value.findIndex(r => r.id === id)
        if (index > -1) {
            rows.value.splice(index, 1)
        }
    }

    function findRowById(id: string): Row | undefined {
        return rows.value.find(r => r.id === id) as Row | undefined
    }

    function getAllCabinets(): Cabinet[] {
        return rows.value.flatMap(row => row.cabinets) as Cabinet[]
    }

    function findCabinetById(id: string): Cabinet | undefined {
        for (const row of rows.value) {
            const cabinet = row.cabinets.find(c => c.id === id)
            if (cabinet) return cabinet as Cabinet
        }
        return undefined
    }

    function getStatistics() {
        const allCabinets = getAllCabinets()
        const totalDevices = allCabinets.reduce((sum, cabinet) => sum + cabinet.deviceCount, 0)
        const totalPower = allCabinets.reduce((sum, cabinet) => sum + cabinet.totalPowerConsumption, 0)

        return {
            rowCount: rows.value.length,
            cabinetCount: allCabinets.length,
            deviceCount: totalDevices,
            totalPowerConsumption: totalPower
        }
    }

    function clearAll(): void {
        rows.value = []
    }

    return {
        config,
        rows,
        addRow,
        removeRow,
        findRowById,
        getAllCabinets,
        findCabinetById,
        getStatistics,
        clearAll
    }
})
